package com.bothin.experiment4.controller;

import com.bothin.experiment4.constant.NoticeNumConstant;
import com.bothin.experiment4.dto.ProductFormDTO;
import com.bothin.experiment4.enums.*;
import com.bothin.experiment4.exception.SellException;
import com.bothin.experiment4.model.LogistInfo;
import com.bothin.experiment4.model.Notice;
import com.bothin.experiment4.model.Product;
import com.bothin.experiment4.model.ProductForm;
import com.bothin.experiment4.service.*;
import com.bothin.experiment4.utils.KeyUtil;
import com.bothin.experiment4.utils.ResultVOUtil;
import com.bothin.experiment4.vo.ResultVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * Created by bothin
 * At 2019/12/19 9:52
 * Description:
 */
@Controller
@RequestMapping("/stockman/manage")
@Slf4j
@Secured("ROLE_USER_STOCKMAN")
public class StockmanManageController {
    @Autowired
    private INoticeService noticeService;
    @Autowired
    private IProductFormService productFormService;
    @Autowired
    private ILogistInfoservice logistInfoservice;
    @Autowired
    private IProductService productService;
    @Autowired
    private IContactDetailService contactDetailService;
    @Autowired
    private IContactService contactService;

    @RequestMapping("/out/list/unhandle")
    @ResponseBody
    public ModelAndView out_list_unhandle(@RequestParam(value = "page", defaultValue = "1") Integer page,
                                          @RequestParam(value = "size", defaultValue = "8") Integer size,
                                          @RequestParam(value = "keyword", defaultValue = "") String keyword,
                                          Map<String, Object> map){
        PageHelper.startPage(page,size);
        List<ProductFormDTO> outFormDTOs = null;
        if (!StringUtils.isEmpty(keyword)){
            outFormDTOs = productFormService.findAllByTypeAndKeywordDTO(ProductFormTypeEnum.OUT_FORM.getCode(),keyword);
            map.put("key","&keyword="+keyword);
        }else {
            outFormDTOs = productFormService.findAllOutUnhandleDTO();
        }
        outFormDTOs = outFormDTOs.stream().peek(e -> {e.setLogistInfo(logistInfoservice.findByFormId(e.getFormId()));})
                .collect(Collectors.toList());
        PageInfo<ProductFormDTO> pageInfo = new PageInfo<>(outFormDTOs);
        map.put("pageInfo",pageInfo);
        //查找阈值
        int notice = noticeService.findNoticeNumById(NoticeNumConstant.NOTICE_NUM_ID);
        map.put("notice",notice);
        map.put("index",1);

        return new ModelAndView("stockman_manage/out/list");
    }

    @RequestMapping("/out/list/handled")
    public ModelAndView out_list_handled(@RequestParam(value = "page", defaultValue = "1") Integer page,
                                 @RequestParam(value = "size", defaultValue = "8") Integer size,
                                 Map<String, Object> map){
        PageHelper.startPage(page,size);
        List<ProductFormDTO> outFormDTOs = productFormService.findAllOutHandledDTO();
        outFormDTOs = outFormDTOs.stream()
                .peek(e -> {e.setLogistInfo(logistInfoservice.findByFormId(e.getFormId()));})
                .collect(Collectors.toList());
        PageInfo<ProductFormDTO> pageInfo = new PageInfo<>(outFormDTOs);
        map.put("pageInfo",pageInfo);
        //查找阈值
        int notice = noticeService.findNoticeNumById(NoticeNumConstant.NOTICE_NUM_ID);
        map.put("notice",notice);
        map.put("index",2);

        return new ModelAndView("stockman_manage/out/list");
    }

    @RequestMapping("/in/list/unhandle")
    public ModelAndView in_list_unhandle(@RequestParam(value = "page", defaultValue = "1") Integer page,
                                         @RequestParam(value = "size", defaultValue = "8") Integer size,
                                         @RequestParam(value = "keyword", defaultValue = "") String keyword,
                                         Map<String, Object> map){
        PageHelper.startPage(page,size);
        List<ProductFormDTO> inFormDTOs = null;
        if (!StringUtils.isEmpty(keyword)){
            inFormDTOs = productFormService.findAllByTypeAndKeywordDTO(ProductFormTypeEnum.IN_FORM.getCode(),keyword);
            map.put("key","&keyword="+keyword);
        }else {
            inFormDTOs = productFormService.findAllInUnhandleDTO();
        }
        inFormDTOs = inFormDTOs.stream().peek(e -> {e.setLogistInfo(logistInfoservice.findByFormId(e.getFormId()));})
                .collect(Collectors.toList());
        PageInfo<ProductFormDTO> pageInfo = new PageInfo<>(inFormDTOs);
        map.put("pageInfo",pageInfo);
        map.put("index",1);

        return new ModelAndView("stockman_manage/in/list");
    }

    @RequestMapping("/in/list/handled")
    public ModelAndView in_list_handled(@RequestParam(value = "page", defaultValue = "1") Integer page,
                                @RequestParam(value = "size", defaultValue = "8") Integer size,
                                Map<String, Object> map){
        PageHelper.startPage(page,size);
        List<ProductFormDTO> inFormDTOs = productFormService.findAllInHandledDTO();
        inFormDTOs = inFormDTOs.stream().peek(e -> {e.setLogistInfo(logistInfoservice.findByFormId(e.getFormId()));})
                .collect(Collectors.toList());
        PageInfo<ProductFormDTO> pageInfo = new PageInfo<>(inFormDTOs);
        map.put("pageInfo",pageInfo);
        map.put("index",2);

        return new ModelAndView("stockman_manage/in/list");
    }

    @RequestMapping("/in/to/add")
    public ModelAndView in_to_add(Map<String, Object> map){
        List<Product> products = productService.findAll();
        map.put("products",products);
        map.put("index",3);
        return new ModelAndView("stockman_manage/in/add");
    }

    @RequestMapping("/in/add")
    public ModelAndView in_add(ProductForm productForm){
        if (StringUtils.isEmpty(productForm.getProductId())||productForm.getProductQuantity()==null){
            log.error("【创建进货单】参数不正确, productForm={}", productForm);
            throw new SellException(ResultEnum.PARAM_ERROR, "/stockman/manage/in/list/handled");
        }

        productForm.setFormId(KeyUtil.genUniqueKey());
        productForm.setFormType(ProductFormTypeEnum.IN_FORM.getCode());
        int finshStatus = 0;
        productForm.setFinshStatus(finshStatus);
        productFormService.insert(productForm);

        //插入物流信息
        logistInfoservice.insert(new LogistInfo(KeyUtil.genUniqueKey(),productForm.getFormId(),"进货专用物流公司", finshStatus));
        return new ModelAndView("redirect:/stockman/manage/in/list/handled");
    }

    @RequestMapping("/in/notice/delete")
    @ResponseBody
    public ResultVO in_notice_delete(@RequestParam("formId") String formId){
        productFormService.deleteById(formId);
        return ResultVOUtil.success();
    }

    /**
     * 对于进货提醒的进货处理
     * @param formId
     * @param productQuantity
     * @return
     */
    @RequestMapping("/in/form/change")
    @Transactional
    @ResponseBody
    public ResultVO in_form_change(@RequestParam("formId") String formId,
                                   @RequestParam("productQuantity") Integer productQuantity){
        ProductForm temp = new ProductForm();
        ProductForm productForm = productFormService.findById(formId);
        if (productForm==null)
            return ResultVOUtil.error(ResultEnum.ERROR.getCode(),ResultEnum.ERROR.getMessage());

        int finshStatus = 0;
        //判断进货值是否大于提醒值（<0）的绝对值
        if (Math.abs(productForm.getProductQuantity())<productQuantity){
            productForm.setProductQuantity(productQuantity);
            productForm.setFinshStatus(finshStatus);//改变完成状态
        }else {
            BeanUtils.copyProperties(productForm,temp);
            formId = KeyUtil.genUniqueKey();
            temp.setFormId(formId);
            temp.setProductQuantity(productQuantity);
            temp.setFinshStatus(finshStatus);//改变完成状态
            productForm.setProductQuantity(productQuantity+productForm.getProductQuantity());
            productFormService.insert(temp);
        }

        productFormService.update(productForm);
        //插入物流信息
        logistInfoservice.insert(new LogistInfo(KeyUtil.genUniqueKey(),formId,"进货专用物流公司", finshStatus));

        return ResultVOUtil.success();
    }

    @RequestMapping("/in/product/add")
    @ResponseBody
    public ResultVO in_product_add(@RequestParam("formId") String formId){
        ProductForm productForm = productFormService.findById(formId);
        if (productForm==null)
            return ResultVOUtil.error(ResultEnum.ERROR.getCode(),ResultEnum.ERROR.getMessage());
        productService.increaseStock(productForm.getProductId(),productForm.getProductQuantity());
        //加完库存后，将进货单的数量重置为负数，表示已经入货完毕
        productForm.setProductQuantity(-productForm.getProductQuantity());
        productFormService.update(productForm);

        return ResultVOUtil.success();
    }

    /**
     * 发货 填写物流
     */
    @RequestMapping("/out/send/add")
    @ResponseBody
    @Transactional
    public ResultVO out_send_add(@RequestParam("formId") String formId,
                                 @RequestParam("logistCompany") String logistCompany){

        ProductForm productForm = productFormService.findById(formId);
        if (productForm==null){
            return ResultVOUtil.error(ResultEnum.SEND_GOODS_ERROR_ISNULL.getCode(),ResultEnum.SEND_GOODS_ERROR_ISNULL.getMessage());
        }
        if( productForm.getFinshStatus() != ProductFormStatusEnum.UNFINISHED.getCode()){
            return ResultVOUtil.error(ResultEnum.SEND_GOODS_ERROR.getCode(),ResultEnum.SEND_GOODS_ERROR.getMessage());
        }

        //减少商品库存
        int res = productService.decreaseStock(productForm.getProductId(), productForm.getProductQuantity());
        //生成进货单的判断状态
        if (res < 0){
            //生成进货单
            productFormService.insert(new ProductForm(KeyUtil.genUniqueKey(),null,productForm.getProductId()
                    ,res, ProductFormTypeEnum.IN_FORM.getCode(),ProductFormStatusEnum.UNFINISHED.getCode()));
            return ResultVOUtil.error(ResultEnum.PRODUCT_STOCK_ERROR.getCode(),ResultEnum.PRODUCT_STOCK_ERROR.getMessage());
        }

        //改变完成状态
        int finshStatus = new Random().nextInt(3);    //生成0~2的随机数来模拟物流信息
        productForm.setFinshStatus(finshStatus);
        productFormService.update(productForm);
        //插入物流信息
        logistInfoservice.insert(new LogistInfo(KeyUtil.genUniqueKey(),formId,logistCompany, finshStatus));
        if (finshStatus==LogistStatusEnum.FINISH.getCode()){
            if (contactDetailService.judgeAllPrintStatusIsZeroById(productForm.getContactId())&&
                    productFormService.judgeAllFinshStatusByContactId(productForm.getContactId()))
                contactService.updatePerformanceStatusById(productForm.getContactId(), ContactStatusEnum.END_PERFORMANCE.getCode());
        }
        return ResultVOUtil.success();
    }

    @RequestMapping("/out/notice/change")
    @ResponseBody
    @Transactional
    public ResultVO notice_change(@RequestParam("notice") Integer notice){
        noticeService.update(new Notice(NoticeNumConstant.NOTICE_NUM_ID,notice));
        return ResultVOUtil.success();
    }
}
